<?php

namespace App\Http\Controllers\Admin\Config;

use App\Http\Controllers\AdminController;
use App\Models\Admin\Permission;
use App\Models\Admin\Role;
use Auth;
use DB;
use Illuminate\Http\Request;
use Log;
use Validator;

class RoleController extends AdminController
{

    /**
     * 获取列表数据
     * @return [type] [description]
     */
    public function getLists(Request $request)
    {
        DB::connection()->enableQueryLog();
        $pageIndex = (int) $request->input('page') ? $request->input('page') : 1;
        $length    = (int) $request->input('length') ? $request->input('length') : 10;
        $start     = ($pageIndex - 1) * $length;

        $where          = [];
        $data['total']  = Role::where($where)->count();
        $data['result'] = [];
        if ($data['total'] > 0) {
            $data['result'] = Role::where($where)->orderBy('name', 'desc')->skip($start)->take($length)->get()->toArray();
        }
        $this->ajaxJson(0, '', $data);
    }

    /**
     * 获取单个角色信息
     * @return [type] [description]
     */
    public function getRole($id, Request $request)
    {
        DB::connection()->enableQueryLog();
        $data = Role::where('id', $id)->with('permissions')->first();
        $this->ajaxJson(0, '', $data);
    }

    /**
     * 获取所有权限列表,根据传递的角色,赋值选中或勾选,并以树形结构展示
     * @return [type] [description]
     */
    public function getTreePermission(Request $request)
    {
        DB::connection()->enableQueryLog();

        $model = Permission::select('id', 'name', 'displayName', 'pid');

        //获取角色所有权限
        $role_id         = $request->input('id');
        $rolePermissions = [];
        if ($role_id) {
            $rolePermissions = DB::table('role_permission')->where('role_id', $role_id)->get();
        }

        $getData = $model->get()->toArray();
        $data    = [];
        //将获得数据重新插入数组,以数据的ID为下标
        foreach ($getData as $value) {
            $data[$value['id']] = $value;
        }
        $parent = array();

        foreach ($data as $key => $value) {
            if (!$value['pid']) {
                $value['title'] = $value['name'] . '【' . $value['displayName'] . '】';
                $parent[]       = $value;
                unset($data[$key]);
            }
        }

        foreach ($parent as $key => $value) {
            $result = $this->formatTreeData($data, $value['id'], $rolePermissions);
            if ($result) {
                $parent[$key]['children'] = $result;
                $parent[$key]['expand']   = false;
                $parent[$key]['checked']  = false;
                $parent[$key]['selected'] = false;
            }
            foreach ($rolePermissions as $rolePermission) {
                if ($rolePermission->permission_id == $value['id']) {
                    $parent[$key]['selected'] = true;
                    $parent[$key]['expand']   = true;
                }
            }
        }
        $this->formatTreeChild($parent);

        $this->ajaxJson(0, '', $parent);
    }

    /**
     * 验证角色名唯一
     * @param  Request $request [description]
     * @return [type]           [description]
     */
    public function checkName(Request $request)
    {
        DB::connection()->enableQueryLog();
        $id   = $request->input('id');
        $name = $request->input('name');
        $this->checkNameUnique($id, $name);
        $this->ajaxJson();
    }

    /**
     * 新增数据
     * @return [type] [description]
     */
    public function insertOne(Request $request)
    {
        $validator = $this->formValidator($request->all());
        if ($validator->fails()) {
            $this->ajaxJson(1, $validator->errors()->first());
        }
        $id   = $request->input('id');
        $name = $request->input('name');
        $this->checkNameUnique($id, $name);
        if ($id > 0) {
            $this->ajaxJson(1, '方式错误,无法更新数据,只能新增数据');
        }
        try {
            DB::connection()->enableQueryLog();
            DB::beginTransaction();
            $role                  = new Role();
            $role->name            = $name;
            $role->displayName     = $request->input('displayName');
            $role->description     = $request->input('description');
            $role->save();

            //解析角色权限列表
            $permissions = $request->input('permission_id');
            $result      = [];
            $this->getChild($permissions, $result);
            $perArr = array_flatten($result);
            $role->permissions()->sync($perArr);
            
            DB::commit();
            $this->ajaxJson(0, '角色添加成功');
        } catch (\Exception $e) {
            DB::rollback();
            Log::error('【' . $e->getMessage() . '】' . '【' . $e->getFile() . '】' . '【' . $e->getTraceAsString() . '】');
            $this->ajaxJson(1, '角色添加失败');
        }
    }
   

    /**
     * 更新
     * @param  Request $request [description]
     * @return [type]           [description]
     */
    public function postUpdate(Request $request)
    {
        $id   = $request->input('id');
        $name = $request->input('name');
        $this->checkNameUnique($id, $name);
        if (!$id) {
            $this->ajaxJson(1, '方式错误,无法新增数据,只能更新数据');
        }

        try {
            $role           = $this->_get_role($id);
            $oldPermissions = $role->permissions()->get();
            DB::beginTransaction();
            DB::table('role')->where('id', $id)->update([
                'name'            => $request->input('name'),
                'displayName'     => $request->input('displayName'),
                'description'     => $request->input('description'),
                'updated_at'      => date('Y-m-d H:i:s'),
            ]);
            //解析角色权限列表
            $permissions = $request->input('permission_id');
            $result      = [];
            $this->getChild($permissions, $result);
            $perArr = array_flatten($result);
            $role->permissions()->sync($perArr);
            
            DB::commit();
            $this->ajaxJson(0, '角色更新成功');
        } catch (\Exception $e) {
            DB::rollback();
            Log::error('【' . $e->getMessage() . '】' . '【' . $e->getFile() . '】' . '【' . $e->getTraceAsString() . '】');
            $this->ajaxJson(1, '角色更新失败');
        }
    }

    /**
     * 删除角色
     * @param  [type] $id [description]
     * @return [type]     [description]
     */
    public function deleteOne($id, Request $request)
    {
        $request->offsetSet('id', $id);
        DB::connection()->enableQueryLog();
        $role = $this->_get_role($id);
        //已用用户使用该角色
        $count = DB::table('role_admin')->where('role_id', $id)->count();
        if ($count > 0) {
            $this->ajaxJson(1, '已有' . $count . '人使用该角色,无法删除!请先转移使用当前角色的用户角色');
        }
        $role->delete();
        $role->permissions()->detach();
        $role->todos()->detach();
        $this->ajaxJson(0, '删除成功');
    }


    /**
     * 表单验证
     * @param  Request $request [description]
     * @return [type]           [description]
     */
    private function formValidator(array $data)
    {
        $attribute = array(
            'id'            => '编号',
            'name'          => '路径地址',
            'displayName'   => '权限名称',
            'permission_id' => '权限列表',
            'todo_id'       => '代办事项模板列表',
            'scoreName'     => '评分类型',
        );

        return Validator::make($data, [
            'id'            => 'bail|required|numeric',
            'name'          => 'bail|required',
            'displayName'   => 'bail|required',
            'permission_id' => 'bail|required|array',
            'todo_id'       => 'bail|array',
            'scoreName'       => 'bail|array',
        ],[], $attribute);
    }

    /**
     * 获取所有子节点的所有值并返回成一维数组
     * @return [type] [description]
     */
    private function getChild($permissions, &$result)
    {
        if (!is_array($permissions)) {
            return false;
        }
        foreach ($permissions as $permission) {
            $result[$permission['id']] = $permission['id'];
            if (isset($permission['children']) && $permission['children'] != '' && count($permission['children']) > 0) {
                $this->getChild($permission['children'], $result);
            }
        }
    }

    /**
     * 格式化树形值
     * 递归到未有子值的数组,将selected的值checked掉
     * 造成该解析的原因是前端框架要求返回每个节点selected,checked值,通过值展示节点是否选中、勾选
     * @return [type] [description]
     */
    private function formatTreeChild(&$data)
    {
        foreach ($data as &$permission) {
            if (isset($permission['children'])) {
                $this->formatTreeChild($permission['children']);
            } else {
                if (isset($permission['selected']) && $permission['selected']) {
                    $permission['checked'] = true;
                }
            }
        }
    }

    /**
     * 格式化树形数据
     * @param  [type] $data [description]
     * @param  [type] $pid  [description]
     * @return [type]       [description]
     */
    private function formatTreeData($data, $pid, $rolePermissions)
    {
        $list = array();
        foreach ($data as $key => $value) {
            if ($value['pid'] == $pid) {
                $value['checked']  = false;
                $value['selected'] = false;
                $result            = $this->formatTreeData($data, $value['id'], $rolePermissions);
                if (!empty($result) && count($result) > 0) {
                    $value['children'] = $result;
                    $value['expand']   = false;
                }
                $value['title'] = $value['name'] . '【' . $value['displayName'] . '】';
                foreach ($rolePermissions as $rolePermission) {
                    if ($rolePermission->permission_id == $value['id']) {
                        $value['selected'] = true;
                        $value['expand']   = true;
                    }
                }
                $list[] = $value;
            }
        }
        return $list;
    }

    /**
     * 验证角色英文名唯一性
     * @param  [int] $id   [角色主键ID]
     * @param  [string] $name [主键英文名]
     * @return [type]       [description]
     */
    private function checkNameUnique($id, $name)
    {
        $unique = Role::where('id', '!=', $id)->where('name', $name)->count();
        if ($unique > 0) {
            $this->ajaxJson(1, '角色名已存在');
        }
        return false;
    }

    /**
     * 获取角色
     * @param  [type] $id [description]
     * @return [type]     [description]
     */
    private function _get_role($id)
    {
        $role = Role::find($id);
        if (!$role) {
            $this->ajaxJson(1, '请求角色数据不存在');
        }
        return $role;
    }
}
